<template>
	<div class="tale-column-setting">
		<div class="form-label flex-align-center">
      {{ props.label }}
      <SvgIcon iconName="icon-plus" class="common-icon" @click="openModal(-1)"></SvgIcon>
    </div>
		<draggable
      tag="ul"
			:list="columns"
			itemKey="key"
			:sort="true"
			class="drag-col-list"
			:group="{ name: 'options' }"
			:animation="300"
      :forceFallback="true"
      ghostClass="ghostClass"
      chosenClass="chosenClass"
      dragClass="dragClass"
      handle=".drag-icon"
		>
      <template #item="{ element, index }">
        <li class="col-item" :class="{
            'col-item-disabled': !element.visible
          }">
          <SvgIcon iconName="icon-drag" className="drag-icon"></SvgIcon>
          <div style="flex: 1;">{{ element.title }}</div>
          <div class="common-icon" @click.stop="toggleDisplay(element)">
            <SvgIcon :iconName="element.visible ? 'icon-eye' : 'icon-eye-close'"></SvgIcon>
          </div>
          <eDropdown
            v-show="element.visible"
            trigger="click"
            placement="top-start"
          >
            <div class="common-icon">
              <SvgIcon iconName="icon-more"></SvgIcon>
            </div>
            <template #list>
              <eDropdownMenu>
                <div class="dropdown-item" @click="openModal(index)">编辑</div>
                <div class="dropdown-item" @click="handleColumnRemove(index)">删除</div>
              </eDropdownMenu>
            </template>
          </eDropdown>
        </li>
      </template>
    </draggable>
	</div>

  <eModal
    v-model="showModal"
    :mask-closable="false"
    :title="`${editIndex === -1 ? '新增' : '编辑'}自定义列`"
    :width="640"
  >
    <eForm ref="formRef" :model="editItem" :rules="rules">
      <eRow :gutter="16">
        <eCol :span="8">
          <eFormItem label="标题" prop="title">
            <eInput v-model="editItem.title"></eInput>
          </eFormItem>
        </eCol>
        <eCol :span="8">
          <eFormItem label="字段名" prop="key">
            <eInput v-model="editItem.key"></eInput>
          </eFormItem>
        </eCol>
        <eCol :span="8">
          <eFormItem label="宽度">
            <eInputNumber v-model="editItem.width" :min="0"></eInputNumber>
          </eFormItem>
        </eCol>
      </eRow>
    </eForm>
    <CodeEditor label="render函数" v-model="editItem.render" style="margin-top: 0;"></CodeEditor>
    <template #footer>
      <eButton @click="showModal = false">取消</eButton>
      <eButton type="primary" @click="handleSave">确定</eButton>
    </template>
  </eModal>
</template>

<script setup lang="ts">
import draggable from 'vuedraggable'
import { computed, reactive, ref, watch, getCurrentInstance } from 'vue'
import type { Form } from 'view-ui-plus';

interface IProps {
	label: string
	modelValue: any
}

const props = withDefaults(defineProps<IProps>(), {
	modelValue: []
})

const emit = defineEmits<{
  (e: 'update:modelValue', data: any[]): void
}>()

const instance = getCurrentInstance()

const columns = ref<any[]>([])

const editIndex = ref(-1)
const editItem = reactive<Record<string, any>>({
  key: '',
  title: '',
  width: null,
  render: ''
})

const showModal = ref(false)
const formRef = ref<InstanceType<typeof Form>>()
const rules = reactive({
  key: [{ required: true, message: '请输入列名', trigger: 'change' }],
  title: [{ required: true, message: '请输入列标题', trigger: 'change' }]
})

watch(
	() => props.modelValue,
	(val) => {
		if (val && val.length) {
      columns.value = val
    }
	},
	{ immediate: true }
)

function openModal(index: number) {
  (formRef.value as any).resetFields()
  editIndex.value = index
  const item = index === -1 ? {
    key: '',
    title: '',
    width: null,
    render: ''
  } : columns.value[index]
  for (const key in item) {
    editItem[key] = item[key]
  }
  showModal.value = true
}

function handleSave() {
  const { $Message } = instance!.appContext.config.globalProperties
  ;(formRef.value as any).validate()
    .then((valid: boolean) => {
      if (valid) {
        if (columns.value.some((i, index) => i.key === editItem.key && index !== editIndex.value)) {
          return $Message.error({
            background: true,
            content: '字段名重复'
          })
        }
        if (editIndex.value === -1) {
          columns.value.push({
            ...editItem,
            visible: true
          })
        } else {
          for (const key in editItem.value) {
            columns.value[editIndex.value][key] = editItem[key]
          }
        }
        showModal.value = false
      }
    })
}

function handleColumnRemove(index: number) {
  columns.value.splice(index, 1)
}

function toggleDisplay(item: any) {
  item.visible = !item.visible
}
</script>

<style lang="less" scoped>
.tale-column-setting {
	width: 100%;
  .form-label {
    height: 24px;
    justify-content: space-between;
    color: #515a6e;
    margin-bottom: 4px;
  }
  .drag-col-list {
    .col-item {
      display: flex;
      align-items: center;
      width: 100%;
      height: 36px;
      line-height: 1;
      padding: 0 4px;
      &-disabled {
        color: #bbbfc4;
      }
      .drag-icon {
        width: 1.2em;
        height: 1.2em;
        margin-right: 8px;
        color: #646a73;
        &:hover {
          cursor: grab;
        }
      }
      &:hover {
        background: rgba(31, 35, 41, 0.08);
        border-radius: 4px;
      }
    }
  }
  .common-icon {
    width: 24px;
    height: 24px;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 2px;
    box-sizing: border-box;
    color: #040b29;
    &:not(:last-child) {
      margin-right: 8px;
    }
    &:hover {
      background: rgba(31, 35, 41, 0.15);
      border-radius: 4px;
      cursor: pointer;
    }
  }
  //拖动排序样式
  .dragClass, .chosenClass {
    border-radius: 4px;
    opacity: 1;
    box-sizing: border-box;
    width: 100%;
  }

  .dragClass {
    box-shadow: 8px 8px 16px rgba(0, 0, 0, 0.3);
    cursor: grab !important;
  }

  .ghostClass {
    opacity: 0 !important;
  }

  .flex-align-center {
    display: flex;
    align-items: center;
  }

  .dropdown-item {
    height: 36px;
    padding: 0 8px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    cursor: pointer;
    color: #040B29;
    margin: 0 8px;
    width: 100px;
    &:hover {
      background: rgba(31, 35, 41, 0.08);
      border-radius: 4px;
    }
  }
}
</style>
